<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        // 构造函数 (构造器 +  原型对象 + 静态对象)
        function Fn(){

        }

        // 输出这个函数原型和构造器
        console.dir(Fn);   // new Fn()

        // 原型  __proto__  
        // 原型对象  prototype   这个构造函数的共有的方法和属性 

        // 原型链   对象在查找属性和方法的过程的链式查找机制    就是原型链  
        
        function Cat(name,color){
            this.name = name;
            this.color=  color;
        }
        // 原型对象接受一些公共的属性和方法 
        Cat.prototype.type = "Cat";
        Cat.prototype.call = function(){
            console.log('喵喵~~')
        }
        Cat.prototype.skill = function(){
            console.log('我会抓老鼠')
        }
        Cat.prototype.say = function(){
            console.log(this.name,this.color);
        }
        // 静态属性
        Cat.hobby = ["睡觉","吃鱼"];
        
        var lucy = new Cat("Lucy","red");
        console.log(lucy)
        console.log(lucy.name)
        console.log(lucy.type);

        console.log(lucy.likes)

        // lucy   ->   lucy.__proto__(Cat.prototype)   =>   Cat.prototype.__proto__  (Object.prototype)   ==>  Object.prototype.__proto__ (null)

        console.log(lucy.__proto__==Cat.prototype);
        console.log(Cat.prototype.__proto__ == Object.prototype)

        // 官方强制规定了  Object.prototype.__proto__ = null 
        console.log( Object.prototype.__proto__ ==null);

        // Object 原型对象的相关方法 
        // constructor: ƒ Object()
        // hasOwnProperty: ƒ hasOwnProperty()
        // isPrototypeOf: ƒ isPrototypeOf()
        // propertyIsEnumerable: ƒ propertyIsEnumerable()
        // toLocaleString: ƒ toLocaleString()
        // toString: ƒ toString()
        // valueOf

        // Object ->  Cat -> lucy 

        // // toString  把其他的类型转成字符串类型 
        // console.log(lucy.toString())

        // // valueOf()  返回实例的值
        // console.log(lucy.valueOf())

        // // instanceof 判断某个实例化对象的原型链 上是否存在 某个构造函数的原型对象 
        // console.log(lucy instanceof Cat); 
        // console.log(lucy instanceof Object); 

        // // isPrototypeOf  判断某个构造函数的原型对象 是否存在  在这个原型链上
        // console.log(Cat.prototype.isPrototypeOf(lucy) )
        // console.log(Object.prototype.isPrototypeOf(lucy) )

        // in   补充判断某个属性是否存在
        console.log("name" in lucy)
        console.log("type" in lucy)
        console.log("likes" in lucy)


        // hasOwnProperty  补充判断某个属性是否存在  (只找实例本身  不会去判断原型 __prtot__ )
        console.log(lucy.hasOwnProperty('name'))
        console.log(lucy.hasOwnProperty('type'))     // 原型对象
        console.log(lucy.hasOwnProperty('likes'))


        console.dir(Array)   // 输出当前构造函数的原型和本身

        var arr = new Array(1,2,3,4)
        console.log(arr)
        console.log(arr.length)

        console.log(arr.valueOf())
        console.log(arr.__proto__ == Array.prototype)
    </script>
</body>
</html>